using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Rensoft.Documents.Accounts.Invoice;
using Rensoft.CRM.Client.Properties;
using Rensoft.CRM.Client.AccountsAPI;
using System.Diagnostics;

namespace Rensoft.CRM.Client
{
    public partial class StatementCreator : Form
    {
        private Account account;
        private List<AccountItem> accountItemList;

        private StatementCreator()
        {
            InitializeComponent();
        }

        public StatementCreator(Account account)
        {
            this.account = account;
            InitializeComponent();
            accountItemList = new List<AccountItem>();

            balanceLabel.Text = account.Balance.ToString("N");
            codeLabel.Text = account.Code;
            nameLabel.Text = account.Title;
            currencyLabel.Text = account.Currency;

            // Give a default rage of 1 month before today's date.
            fromDateCalendar.SelectionStart = DateTime.Today.AddMonths(-1);
        }

        protected override void OnLoad(EventArgs e)
        {
            UseWaitCursor = true;
            loadBackgroundWorker.RunWorkerAsync();

            base.OnLoad(e);
        }

        private void _acceptButton_Click(object sender, EventArgs e)
        {
            CreateDocument();
            DialogResult = DialogResult.None;
        }

        private void pdfBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (e.Argument is PdfStatement)
            {
                PdfStatement statement = e.Argument as PdfStatement;
                statement.Save(saveFileDialog.FileName);
                Process.Start(saveFileDialog.FileName);
            }
            else
            {
                throw new InvalidOperationException(
                    "PDF background worker was started with an argument type other than PdfStatement.");
            }
        }

        private void pdfBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Close();
        }

        public void CreateDocument()
        {
            UseWaitCursor = true;

            PdfStatementDetails details = new PdfStatementDetails();
            details.StatementDate = DateTime.Now;
            details.FromDate = fromDateCalendar.SelectionStart.Date;
            details.AccountCode = account.Code;
            details.AccountName = account.Title;
            details.Currency = account.Currency;

            details.ItemList = new List<PdfStatementItem>();
            foreach (AccountItem accountItem in accountItemList)
            {
                PdfStatementItem item = new PdfStatementItem();
                item.Amount = accountItem.ValueAmount;
                item.Date = accountItem.Date;

                if (accountItem is Invoice)
                {
                    Invoice invoice = accountItem as Invoice;
                    item.Transaction = "Invoice " + invoice.InvoiceRef +
                        " - Due " + invoice.Date.ToShortDateString();
                }
                else if (accountItem is Credit)
                {
                    Credit credit = accountItem as Credit;
                    item.Transaction = "Credit - " + credit.Reference;

                    if (credit.Direction == CreditDirection.Recieve)
                    {
                        // Use negative value to balance.
                        item.Amount *= -1;
                    }
                }
                else if (accountItem is Payment)
                {
                    Payment payment = accountItem as Payment;
                    item.Transaction = "Payment - " + payment.PaymentTypeString;

                    if (payment.Direction == PaymentDirection.Recieve)
                    {
                        // Use negative value to balance.
                        item.Amount *= -1;
                    }
                }

                // Capture items in between the start and end dates.
                if ((accountItem.Date.Date >= fromDateCalendar.SelectionStart.Date) &&
                    (accountItem.Date.Date <= toDateCalendar.SelectionStart.Date))
                {
                    details.ItemList.Add(item);
                }

                // If before date (do not include items after the end date).
                if (accountItem.Date.Date < fromDateCalendar.SelectionStart.Date)
                {
                    details.OpeningBalance += item.Amount;
                }
            }

            PdfStatement statement = new PdfStatement(
                Settings.Default.StatementTemplate, details);

            string fileName = string.Format(
                Settings.Default.StatementFilenameFormat,
                account.Code, details.DateCode);

            saveFileDialog.InitialDirectory = Settings.Default.StatementDirectory;
            saveFileDialog.FileName = fileName;

            UseWaitCursor = false;
            DialogResult result = saveFileDialog.ShowDialog(this);

            if (result == DialogResult.OK)
            {
                UseWaitCursor = true;
                pdfBackgroundWorker.RunWorkerAsync(statement);
            }
        }

        private void loadBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            AccountsService accountsService = AccountsService.CreateInstance();

            accountItemList.Clear();
            accountItemList.AddRange(accountsService.CreditFetchByAccountId(account.AccountId));
            accountItemList.AddRange(accountsService.PaymentFetchByAccountId(account.AccountId));
            accountItemList.AddRange(accountsService.InvoiceFetchByAccountId(account.AccountId));

            Comparison<AccountItem> itemCompare = new Comparison<AccountItem>(compareAccountItem);
            accountItemList.Sort(itemCompare);
        }

        private int compareAccountItem(AccountItem left, AccountItem right)
        {
            if (left.Date > right.Date)
            {
                return 1;
            }

            if (left.Date < right.Date)
            {
                return -1;
            }

            return 0;
        }

        private void loadBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            LoadContactsAsync();
        }

        protected void LoadContactsAsync()
        {
            // Assume wait cursor in use, and contacts combo box already disabled.
            contactsBackgroundWorker.RunWorkerAsync();
        }

        private void contactsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            AccountsService accountsService = AccountsService.CreateInstance();

            List<string> contactGuidList = new List<string>(
                accountsService.AccountFetchContactGuids(account.AccountId));
        }

        private void contactsBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (contactsComboBox.Items.Count > 0)
            {
                contactsComboBox.SelectedIndex = 0;
                contactsComboBox.Enabled = true;
            }

            UseWaitCursor = false;
            _acceptButton.Enabled = true;
        }
    }
}